import 'package:casdon/modules/recipe/data/model/category_recipe_model.dart';
import 'package:casdon/modules/recipe/domain/states/category_recipe_list_state.dart';
import 'package:casdon/modules/recipe/domain/usecase/category_recipe_list_usecase.dart';
import 'package:casdon/modules/recipe/ui/widgets/Recipe_card_item.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class CategoryRecipeListNotifier
    extends AutoDisposeFamilyAsyncNotifier<CategoryRecipeListState, String> {
  late final String moduleId;
  final int pageSize = 10;
  bool _isRefreshing = false;
  KeepAliveLink? _keepAliveLink;

  @override
  Future<CategoryRecipeListState> build(String arg) async {
    moduleId = arg;
    ref.onDispose(() {
      _keepAliveLink?.close();
      _keepAliveLink = null;
    });
    ref.onResume(() {
      Future.microtask(() => _refreshSilently());
    });

    final cached = state.valueOrNull;
    if (cached != null && cached.data.isNotEmpty) {
      _updateKeepAlive(cached);
      Future.microtask(() => _refreshSilently());
      return cached;
    }

    final fresh = await _fetchData(page: 1);
    _updateKeepAlive(fresh);
    return fresh;
  }

  Future<void> refresh() async {
    await _refreshSilently(force: true);
  }

  Future<void> loadMore() async {
    final current = state.valueOrNull;
    if (current == null || current.isLoadingMore || !current.hasMore) return;

    final loadingState = current.copyWith(isLoadingMore: true);
    state = AsyncValue.data(loadingState);

    final nextPage = current.pageNum + 1;
    try {
      final nextState = await _fetchData(page: nextPage, previous: current);
      if (nextState.data.isEmpty || nextState.pageNum == current.pageNum) {
        final fallback = current.copyWith(
          isLoadingMore: false,
          hasMore: false,
        );
        state = AsyncValue.data(fallback);
        _updateKeepAlive(fallback);
        return;
      }

      final merged = current.copyWith(
        data: [...current.data, ...nextState.data],
        pageNum: nextPage,
        hasMore: nextState.hasMore,
        isLoadingMore: false,
      );

      state = AsyncValue.data(merged);
      _updateKeepAlive(merged);
    } catch (_) {
      final fallback = current.copyWith(isLoadingMore: false);
      state = AsyncValue.data(fallback);
      _updateKeepAlive(fallback);
    }
  }

  Future<void> _refreshSilently({bool force = false}) async {
    if (_isRefreshing) return;
    _isRefreshing = true;
    final previous = state.valueOrNull;
    try {
      final fresh = await _fetchData(page: 1, previous: previous);
      state = AsyncValue.data(fresh);
      _updateKeepAlive(fresh);
    } catch (_) {
      if (force && previous != null) {
        state = AsyncValue.data(previous);
      }
    } finally {
      _isRefreshing = false;
    }
  }

  Future<CategoryRecipeListState> _fetchData({
    required int page,
    CategoryRecipeListState? previous,
  }) async {
    final fallback = previous ?? state.valueOrNull;
    try {
      final ret = await ref
          .read(categoryRecipeListUsecaseProvider)
          .execute(id: moduleId, pageNum: page, pageSize: pageSize);

      final rows = ret.rows ?? [];
      if (rows.isEmpty) {
        return fallback?.copyWith(
              isLoadingMore: false,
              pageNum: page,
              hasMore: false,
            ) ??
            CategoryRecipeListState.initial().copyWith(
              pageNum: page,
              hasMore: false,
            );
      }

      final items = CategoryRecipeModel.listFromApi(rows);
      final consumed = (page - 1) * pageSize + items.length;
      final hasMore = ret.total > consumed;

      return CategoryRecipeListState(
        data: items,
        pageNum: page,
        hasMore: hasMore,
        isLoadingMore: false,
      );
    } catch (_) {
      return fallback?.copyWith(isLoadingMore: false) ??
          CategoryRecipeListState.initial().copyWith(pageNum: page);
    }
  }

  void _updateKeepAlive(CategoryRecipeListState data) {
    if (data.data.isNotEmpty) {
      _keepAliveLink ??= ref.keepAlive();
    } else {
      _keepAliveLink?.close();
      _keepAliveLink = null;
    }
  }
}

final categoryRecipeListProvider =
    AutoDisposeAsyncNotifierProviderFamily<
      CategoryRecipeListNotifier,
      CategoryRecipeListState,
      String
    >(CategoryRecipeListNotifier.new);
